
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.util.ArrayList;
import javax.swing.border.TitledBorder;

public class GererListe extends JDialog implements ActionListener, KeyListener {

  private JPanel pRech;
  private JPanel pRes;
  private JPanel pAjout;
  private JPanel pSup;
  private JTable tRes;
  private JTable tAjo;
  private JLabel lTri;
  private JTextField tNomTri;
  private JRadioButton rASC;
  private JRadioButton rDESC;
  private JLabel lCat;
  private JComboBox cbCat;
  private JButton bRech;
  private JButton bAjo;
  private JButton bSup;
  private JButton bQuit;
  private Container contenu;
  private ButtonGroup bg;
  private JLabel lQte;
  private JLabel lOrdre;
  private JFormattedTextField tQte;
  private JLabel lResp;
  private JComboBox cResp;
  private Liste liste;
  private JScrollPane scroll;
  private JScrollPane scroll2;
  private ArrayList<LigneListe> lignes;

  public GererListe(Liste liste) {
    // Création de la fenêtre
    super((JDialog) null, true);
    this.liste = liste;
    this.setTitle("Modification d'une liste : " + this.liste.getNom());
    this.setLayout(null);
    int i; // Utilisé pour boucles etc...

    // Ajout des différents panneaux de la fenêtre
    this.pRech = new JPanel(null, false);
    this.pRech.setBorder(new TitledBorder(null, "Recherche d'élément", TitledBorder.LEFT, TitledBorder.DEFAULT_POSITION));

    this.pRes = new JPanel(null, false);
    this.pRes.setBorder(new TitledBorder(null, "Elément de la liste", TitledBorder.LEFT, TitledBorder.DEFAULT_POSITION));

    this.pAjout = new JPanel(null, false);
    this.pAjout.setBorder(new TitledBorder(null, "Outil d'ajout", TitledBorder.LEFT, TitledBorder.DEFAULT_POSITION));

    this.pSup = new JPanel(null, false);
    this.pSup.setBorder(new TitledBorder(null, "Outil de suppression", TitledBorder.LEFT, TitledBorder.DEFAULT_POSITION));

    String[] name = new String[]{"Description", "Catégorie", "Quantité"};

    // Chargement des JTable avec les données de la base
    this.loadTableauLignes(true);
    this.loadTableauElem(true, false);

    // Création des composants
    this.bRech = new JButton("Recherche");
    this.bRech.addActionListener(this);

    this.bSup = new JButton("Supprimer");
    this.bSup.addActionListener(this);

    this.bQuit = new JButton("Quitter");
    this.bQuit.addActionListener(this);

    this.bAjo = new JButton("Ajouter");
    this.bAjo.addActionListener(this);

    this.lQte = new JLabel("Quantité :");
    this.tQte = new JFormattedTextField(NumberFormat.getIntegerInstance());
    this.tQte.addKeyListener(this);

    // Liste des responsables = users
    this.lResp = new JLabel("Responsables :");
    ArrayList<User> resps = null;
    try {
      resps = User.chargerUsers();
    } catch (SQLException errUser) {
      JOptionPane.showMessageDialog(this, "Erreur dans le chargement des listes \n" + errUser, "Erreur BDD", JOptionPane.ERROR_MESSAGE);
    }
    String[] listeResp = new String[resps.size()];
    i = 0;
    for (User r : resps) {
      listeResp[i] = r.getNom();
      i++;
    }
    this.cResp = new JComboBox(listeResp);
    this.cResp.setMaximumRowCount(5);

    // Liste des catégories d'Elements
    ArrayList<Categorie> categs = null;
    try {
      categs = Categorie.chargerCategories();
    } catch (SQLException errUser) {
      JOptionPane.showMessageDialog(this, "Erreur dans le chargement des catégories \n" + errUser, "Erreur BDD", JOptionPane.ERROR_MESSAGE);
    }
    String[] listeCategs = new String[categs.size() + 1];
    listeCategs[0] = "Toutes";
    i = 1;
    for (Categorie c : categs) {
      listeCategs[i] = c.getNom();
      i++;
    }
    this.cbCat = new JComboBox(listeCategs);
    this.cbCat.setMaximumRowCount(5);


    this.lTri = new JLabel("Nom : ");
    this.tNomTri = new JTextField();
    this.tNomTri.addKeyListener(this);

    this.lCat = new JLabel("Categorie : ");
    this.lOrdre = new JLabel("Par ordre :");

    /**         radiobutton */
    this.bg = new ButtonGroup();
    this.rASC = new JRadioButton("Croissant", true);
    this.rDESC = new JRadioButton("Decroissant");
    this.bg.add(this.rASC);
    this.bg.add(this.rDESC);

    this.contenu = this.getContentPane();
    this.contenu.setLayout(null);

    // Ajout des composants
    this.pRech.add(this.lTri);
    this.pRech.add(this.tNomTri);
    this.pRech.add(this.bRech);
    this.pAjout.add(this.bAjo);
    this.pAjout.add(this.lQte);
    this.pAjout.add(this.tQte);
    this.pAjout.add(this.lResp);
    this.pAjout.add(this.cResp);
    this.pRech.add(this.cbCat);
    this.pRech.add(this.lCat);
    this.pRech.add(this.lOrdre);
    this.pRech.add(this.rASC);
    this.pRech.add(this.rDESC);
    this.pSup.add(this.bSup);
    this.pAjout.add(this.bQuit);
    this.pRes.add(this.scroll);
    this.pRech.add(this.scroll2);
    this.contenu.add(this.pRes);
    this.contenu.add(this.pRech);
    this.contenu.add(this.pAjout);
    this.contenu.add(this.pSup);

    // Positionnement
    this.pRes.setBounds(10, 10, 350, 225);
    this.pRech.setBounds(10, 250, 350, 340);
    this.pAjout.setBounds(380, 250, 150, 225);
    this.pSup.setBounds(380, 10, 150, 300);
    this.scroll.setBounds(10, 30, 330, 190);
    this.scroll2.setBounds(10, 150, 320, 170);
    this.lTri.setBounds(15, 30, 150, 20);
    this.tNomTri.setBounds(130, 30, 150, 20);
    this.cbCat.setBounds(130, 60, 150, 20);
    this.lCat.setBounds(15, 60, 100, 20);
    this.lOrdre.setBounds(15, 90, 75, 20);
    this.rASC.setBounds(100, 90, 100, 20);
    this.rDESC.setBounds(220, 90, 100, 20);
    this.bRech.setBounds(100, 120, 105, 20);
    this.bAjo.setBounds(25, 30, 100, 20);
    this.bSup.setBounds(25, 80, 100, 20);
    this.lQte.setBounds(25, 60, 100, 20);
    this.tQte.setBounds(100, 60, 30, 20);
    this.lResp.setBounds(25, 90, 100, 20);
    this.cResp.setBounds(20, 120, 110, 20);
    this.bQuit.setBounds(25, 180, 100, 20);

    this.setBounds(20, 20, 600, 640);
    this.setResizable(false);
    this.setVisible(true);
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == this.bRech) {
      this.loadTableauElem(false, true);
    }
    if (e.getSource() == this.bAjo) {
      this.actionAjouter();
    }
    if (e.getSource() == this.bQuit) {
      this.dispose();
    }
    if (e.getSource() == this.bSup) {
      this.actionSupprLigne();
    }
  }

  // Gère l'action de suppression d'une ligne
  private void actionSupprLigne() {
    int selection = this.tRes.getSelectedRow();
    if (selection >= 0) {
      if (this.tRes.getSelectedRowCount() == 1) {
        try {

          // On recherche la liste sélectionnée, si trouvée on supprime
          for (LigneListe l : this.lignes) {
            if (l.getElem().getNom().equals((String) this.tRes.getValueAt(selection, 0))
                    && l.getElem().getCategorie().getNom().equals((String) this.tRes.getValueAt(selection, 1))
                    && l.getQte() == Integer.parseInt((String) this.tRes.getValueAt(selection, 2))
                    && l.getResp().getNom().equals((String) this.tRes.getValueAt(selection, 3))) {
              l.delete();
              break;
            }
          }
          this.loadTableauLignes(false);

        } catch (SQLException errSupprLigne) {
          JOptionPane.showMessageDialog(this, "Impossible de supprimer la ligne", "Erreur BDD", JOptionPane.ERROR_MESSAGE);
        }
      } else {
        JOptionPane.showMessageDialog(this, "Vous ne pouvez sélectionner qu'une seule liste", "Modifier la liste", JOptionPane.ERROR_MESSAGE);
      }
    } else {
      JOptionPane.showMessageDialog(this, "Vous devez sélectionner une liste", "Modifier la liste", JOptionPane.ERROR_MESSAGE);
    }
  }

  // Charge le tableau des lignes de la liste
  private void loadTableauLignes(boolean callFromConstructor) {
    String[] colonnes = new String[]{"Description", "Catégorie", "Quantité", "Responsable"};

    ArrayList<LigneListe> lignes = null;
    try {
      lignes = LigneListe.chargerLignesListe(this.liste);
    } catch (SQLException e) {
      JOptionPane.showMessageDialog(this, "Erreur dans le chargement des lignes \n" + e, "Erreur BDD", JOptionPane.ERROR_MESSAGE);
    }

    this.lignes = lignes;

    Object[][] lignesTab = new String[lignes.size()][4];
    int i = 0;
    for (LigneListe l : lignes) {
      lignesTab[i] = new String[]{l.getElem().getNom(), l.getElem().getCategorie().getNom(), String.valueOf(l.getQte()), l.getResp().getNom()};
      i++;
    }

    // On met à jour le tableau en enlevant l'ancien et en le reconstruisant

    if (!callFromConstructor) {
      this.pRes.remove(this.scroll);
    }

    this.tRes = new JTable(lignesTab, colonnes);
    this.scroll = new JScrollPane(this.tRes);

    this.scroll.setBounds(10, 30, 330, 190);
    this.scroll.createVerticalScrollBar();

    this.pRes.add(this.scroll);
  }

  // Charge le tableau des élements
  private void loadTableauElem(boolean callFromConstructor, boolean tri) {
    String[] colonnes = new String[]{"ID", "Description", "Catégorie"};

    ArrayList<Item> items = null;
    try {
      if (tri) {
        String ordre = new String("DESC");
        if (this.rASC.isSelected()) {
          ordre = "ASC";
        }
        items = Item.getItemByName(this.tNomTri.getText(), ordre);
      } else {
        items = Item.chargerItems();
      }
    } catch (SQLException e) {
      JOptionPane.showMessageDialog(this, "Erreur dans le chargement des items \n" + e, "Erreur BDD", JOptionPane.ERROR_MESSAGE);
    }

    if (tri) {
      String cat = (String) this.cbCat.getSelectedItem();
      ArrayList<Item> trash = new ArrayList<Item>();
      if (!cat.equals("Toutes")) {
        for (Item it : items) {
          if (!it.getCategorie().getNom().equals(cat)) {
            trash.add(it);
          }
        }

        for (Item it : trash) {
          items.remove(it);
        }
      }
    }

    Object[][] itemTab = new String[items.size()][3];
    int i = 0;
    for (Item it : items) {
      itemTab[i] = new String[]{String.valueOf(it.getId()), it.getNom(), it.getCategorie().getNom()};
      i++;
    }

    // On met à jour le tableau en enlevant l'ancien et en le reconstruisant

    if (!callFromConstructor) {
      this.pRech.remove(this.scroll2);
    }

    this.tAjo = new JTable(itemTab, colonnes);
    this.scroll2 = new JScrollPane(this.tAjo);

    this.scroll2.setBounds(10, 150, 320, 170);
    this.scroll2.createVerticalScrollBar();

    this.pRech.add(this.scroll2);
  }

  // Gère l'action de l'ajout d'un element à la liste
  private void actionAjouter() {
    int selection = this.tAjo.getSelectedRow();
    if (selection >= 0) {
      if (this.tAjo.getSelectedRowCount() == 1) {
        try {
          this.ajoutLigne(this.liste, this.getSelectedItem(selection), this.getSelectedUser());
        } catch (SQLException errAjoutLigne) {
          JOptionPane.showMessageDialog(this, "Impossible d'ajouter l'element à la base de donnée", "Erreur BDD", JOptionPane.ERROR_MESSAGE);
        }
      } else {
        JOptionPane.showMessageDialog(this, "Vous ne pouvez sélectionner qu'un seul élément", "Modifier l'élément", JOptionPane.ERROR_MESSAGE);
      }
    } else {
      JOptionPane.showMessageDialog(this, "Vous devez sélectionner un élément", "Modifier l'élément", JOptionPane.ERROR_MESSAGE);
    }
  }

  // Ajout d'une ligne à la liste
  private void ajoutLigne(Liste liste, Item item, User user) throws SQLException {
    int qte = 0;
    try {
      qte = Integer.parseInt(this.tQte.getText());
    } catch (NumberFormatException errQte) {
      JOptionPane.showMessageDialog(this, "Veuillez saisir une quantité correcte.", "Erreur Saisie", JOptionPane.ERROR_MESSAGE);
    }

    if (qte > 0) {
      try {
        LigneListe ll = new LigneListe(liste.getListID(), item, user, qte);
      } catch (SQLException pbAjoutListe) {
        throw pbAjoutListe;
      }
      this.loadTableauLignes(false);
    } else if (qte != 0) {
      JOptionPane.showMessageDialog(this, "Veuillez saisir une quantité positive.", "Erreur Saisie", JOptionPane.ERROR_MESSAGE);
    }
  }

  // Retour l'item sélectionné dans la comboBox
  private Item getSelectedItem(int selection) throws SQLException {
    return new Item(Integer.parseInt((String) this.tAjo.getValueAt(selection, 0)),
            (String) this.tAjo.getValueAt(selection, 1),
            Categorie.getCategorieNom((String) this.tAjo.getValueAt(selection, 2)));
  }

  // Retour l'user sélectionné dans la comboBox Responsable
  private User getSelectedUser() throws SQLException {
    String resp = (String) this.cResp.getSelectedItem();
    return User.getUser(resp);
  }

  public void keyTyped(KeyEvent ke) {
  }

  public void keyPressed(KeyEvent ke) {
    int key = ke.getKeyCode();
    switch (key) {
      case KeyEvent.VK_ESCAPE:
        this.dispose();
        break;
      case KeyEvent.VK_ENTER:
        if (ke.getSource() == this.tQte) {
          this.actionAjouter();
        } else if (ke.getSource() == this.tNomTri) {
          this.loadTableauElem(false, true);
        }
        break;
    }
  }

  public void keyReleased(KeyEvent ke) {
  }
}
